package com.platform.common.util;

import com.alibaba.fastjson.JSONObject;
import org.codehaus.jackson.map.ObjectMapper;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * xml报文处理工具
 * @Desc XmlUtil.java
 * @author liuli
 * @Date   2014年7月4日
 */
public class XmlUtil {
	public static Logger log = LoggerFactory.getLogger(XmlUtil.class);
	public static String LoadJsonFile(String filePath){
		File file = new File(filePath);
	    BufferedReader reader = null;
	    String laststr = "";
	    try {  
	        reader = new BufferedReader(new FileReader(file));
	        String tempString = null;
	        while ((tempString = reader.readLine()) != null) {  
	            laststr = laststr + tempString;  
	        }  
	        reader.close();  
	    } catch (IOException e) {
	      System.out.println(e.getMessage());
	    } finally {  
	        if (reader != null) {  
	            try {  
	                reader.close();  
	            } catch (IOException e1) {
	            }  
	        }  
	    }
		return laststr;  
	}
	
/**
   * 得到当前系统日期 author: LIULI
   * @return 当前日期的格式字符串,日期格式为"yyyy-MM-dd"
   */
	  public static String getCurrentDate() {
	    String pattern = "yyyy-MM-dd";
	    SimpleDateFormat df = new SimpleDateFormat(pattern);
	    Date today = new Date();
	    String tString = df.format(today);
	    return tString;
	  }
  /**
   * 得到当前系统时间 author: LIULI
   * @return 当前时间的格式字符串，时间格式为"HH:mm:ss"
   */
	  public static String getCurrentTime() {
	    String pattern = "HH:mm:ss";
	    SimpleDateFormat df = new SimpleDateFormat(pattern);
	    Date today = new Date();
	    String tString = df.format(today);
	    return tString;
	  }
 /**
 * 获取javabean方法名
 * @param str
 * @return
 */
	static String getBeanName(String str) {
		String retStr;
		if (str.length() >= 2 && isString(String.valueOf(str.charAt(0))) == "0"
				&& isString(String.valueOf(str.charAt(1))) == "1") {
			retStr = str;
		} else {
			retStr = str.substring(0, 1).toUpperCase()
					+ str.substring(1, str.length());
		}
		return retStr;
	}
/**
 * 判断是否是字母
 * @param str
 * @return "":不是字母 ；  1 大写 ； 0小写 
 */
	static String isString(String str) {
		String flag = "";
		if (str.charAt(0) <= 'Z' && str.charAt(0) >= 'A') {
			flag = "1";
		} else if (str.charAt(0) <= 'z' && str.charAt(0) >= 'a') {
			flag = "0";
		}
		return flag;
	}
	/**
	 * 把map的值 按照bean的接口取出来 组成xml 【bean字段必须大写】
	 * @param javaBeanInstance
	 * @param mMap
	 * @return
	 * @throws Exception
	 */
	public static StringBuilder mapToBeanXML(Object javaBeanInstance, Map mMap)throws Exception {
		StringBuilder Xml = new StringBuilder();
		Object obj = null;
		String javaBeanPath =javaBeanInstance.getClass().getName();
	  	Class<?> clas = Class.forName(javaBeanPath);
	    if(!(clas.isInstance(javaBeanInstance))){
	   	 log.error("传入的java实例与配置的java对象类型不符！");
	    }
	    obj=clas.newInstance();
	    Field[] fields = clas.getDeclaredFields();
	    for (int i = 0; i < fields.length; i++) {//获取所有字段
		   	 Field mField = fields[i];//字段名
		   	 String key =getBeanName(mField.getName());
		   	 String value ="";
		   	 try {
				value = (String) mMap.get(key);
				if (value == null) {
					value ="";
				}
				Xml.append("<"+key+">"+value+"</"+key+">");
			} catch (Exception e) {
				// TODO: handle exception
			}
	     
	    }
	return Xml;	
}
	/**
	 * 把map的值 按照bean的接口取出来 组成xml  【bean字段可以忽略大小写,在map中取值时自动转换成大写】
	 * @param javaBeanInstance
	 * @param mMap
	 * @return
	 * @throws Exception
	 */
	public static StringBuilder mapToBeanXMLEx(Object javaBeanInstance, Map mMap)throws Exception {
		StringBuilder Xml = new StringBuilder();
		Object obj = null;
		String javaBeanPath =javaBeanInstance.getClass().getName();
	  	Class<?> clas = Class.forName(javaBeanPath);
	    if(!(clas.isInstance(javaBeanInstance))){
	   	 log.error("传入的java实例与配置的java对象类型不符！");
	    }
	    obj=clas.newInstance();
	    Field[] fields = clas.getDeclaredFields();
	    for (int i = 0; i < fields.length; i++) {//获取所有字段
		   	 Field mField = fields[i];//字段名
		   	 String key =getBeanName(mField.getName());
		   	 String value ="";
		   	 try {
				value = (String) mMap.get(key.toUpperCase());
				if (value == null) {
					value ="";
				}
				Xml.append("<"+key+">"+value+"</"+key+">");
			} catch (Exception e) {
				// TODO: handle exception
			}
	     
	    }
	return Xml;	
}
	/**
	 * map  to bean
	 * @param javaBeanInstance
	 * @param mMap
	 * @return
	 * @throws Exception
	 */
	public static Object mapToBean(Object javaBeanInstance, Map mMap)throws Exception {
		Object obj = null;
	  	 String javaBeanPath =javaBeanInstance.getClass().getName();
	  	 Class<?> clas = Class.forName(javaBeanPath);
	    if(!(clas.isInstance(javaBeanInstance))){
	   	 log.error("传入的java实例与配置的java对象类型不符！");
	    }
	    obj=clas.newInstance();
	    Field[] fields = clas.getDeclaredFields();
	    for (int i = 0; i < fields.length; i++) {//获取所有字段
	   	 Method mMethod = null;//方法名
	   	 Field mField = fields[i];//字段名
	   	 String name = "set"+getBeanName(mField.getName());//获取set方法
	   	 mMethod = clas.getDeclaredMethod(name,String.class);
	   	 String value ="";
	   	 try {
			value = (String) mMap.get(getBeanName(mField.getName()));
			if (value == null) {
				value ="";
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	      mMethod.invoke(obj, value);
	    }
		return obj;	
	}
/**
 * 把xml的值自动打包成javabean
 * @param javaBeanInstance
 * @param vElement
 * @return
 * @throws Exception 把异常抛出去
 */
	public static Object xmlToBean(Object javaBeanInstance, Element vElement) throws Exception{
		 Object obj = null;
	   	 try {
	   		String javaBeanPath =javaBeanInstance.getClass().getName();
		   	 Class<?> clas = Class.forName(javaBeanPath);
		     if(!(clas.isInstance(javaBeanInstance))){
		    	 log.error("传入的java实例与配置的java对象类型不符！");
		     }
		     obj=clas.newInstance();
		     Field[] fields = clas.getDeclaredFields();
		     for (int i = 0; i < fields.length; i++) {//获取所有字段
		    	 Method mMethod = null;//方法名
		    	 Field mField = fields[i];//字段名
		    	 String name = "set"+getBeanName(mField.getName());//获取set方法
		    	  try {
		    		  mMethod = clas.getDeclaredMethod(name,String.class);
		    		  String value =vElement.getChildText(mField.getName());
		    		  if (value == null) {
		    			  value ="";
					  }
			       	  // log.debug("=======key:"+mField.getName()+"=======value:"+vElement.getChildText(mField.getName()));
			          mMethod.invoke(obj, value);
				} catch (Exception e) {
					// TODO: handle exception
				}
		     }
		} catch (Exception e) {
			throw new Exception("报文格式错误 错误节点UIS系统实体类："+javaBeanInstance.getClass().getSimpleName());
		}
		return obj;	
	}
	/**
	 * ADD  CDATE 处理特殊字符
	 * javabean生成  xml
	 * @param javaBeanInstance  一个javabean实例
	 * @param flag   Y 显示  ; N不显示
	 * @return
	  * @throws Exception 把异常抛出去
	 */
		public static StringBuilder beanToXmlCDATA(Object javaBeanInstance, String flag)throws Exception {
			StringBuilder Xml = new StringBuilder();
	    	String javaBeanPath =javaBeanInstance.getClass().getName();
		     Class<?> clas = Class.forName(javaBeanPath);
		     if(!(clas.isInstance(javaBeanInstance))){
		    	 log.error("传入的java实例与配置的java对象类型不符！");
		        return Xml;
		     }
		     Field[] fields = clas.getDeclaredFields();
		     for (int i = 0; i < fields.length; i++) {
		    	 Method mMethod = null;//方法名
		    	 Field mField = fields[i];//字段名
		    	 String value ="";
				 String name = "get"+getBeanName(mField.getName());
				 mMethod = clas.getDeclaredMethod(name); 
				 try {
					 value = mMethod.invoke(javaBeanInstance).toString();
				} catch (Exception e) {
				//	log.error(e);
				};
				 if ("".equals(value) || value ==null) {
					 if ("N".equals(flag)) {
						;
					}else{
						Xml.append("<"+mField.getName()+"><![CDATA["+value+"]]></"+mField.getName()+">");
					}
				}else{
					Xml.append("<"+mField.getName()+"><![CDATA["+value+"]]></"+mField.getName()+">");
				}
			}	     	
		    return Xml;
		}
/**
 * javabean生成  xml
 * @param javaBeanInstance  一个javabean实例
 * @param flag   Y 显示  ; N不显示
 * @return
  * @throws Exception 把异常抛出去
 */
	public static StringBuilder beanToXml(Object javaBeanInstance, String flag)throws Exception {
		StringBuilder Xml = new StringBuilder();
    	String javaBeanPath =javaBeanInstance.getClass().getName();
	     Class<?> clas = Class.forName(javaBeanPath);
	     if(!(clas.isInstance(javaBeanInstance))){
	    	 log.error("传入的java实例与配置的java对象类型不符！");
	        return Xml;
	     }
	     Field[] fields = clas.getDeclaredFields();
	     for (int i = 0; i < fields.length; i++) {
	    	 Method mMethod = null;//方法名
	    	 Field mField = fields[i];//字段名
	    	 String value ="";
			 String name = "get"+getBeanName(mField.getName());
			 mMethod = clas.getDeclaredMethod(name); 
			 try {
				 value = mMethod.invoke(javaBeanInstance).toString();
			} catch (Exception e) {
			//	log.error(e);
			};
			 if ("".equals(value) || value ==null) {
				 if ("N".equals(flag)) {
					;
				}else{
					Xml.append("<"+mField.getName()+">"+value+"</"+mField.getName()+">");
				}
			}else{
				Xml.append("<"+mField.getName()+">"+value+"</"+mField.getName()+">");
			}
		}	     	
	    return Xml;
	}
/**
 * javabean生成  xml
 * @param javaBeanInstance  一个javabean实例
 * @param flag   Y 显示  ; N不显示
 * @return
 */
	public static StringBuilder ObjectbeanToXml(Object javaBeanInstance, String flag)throws Exception {
		StringBuilder Xml = new StringBuilder();
    	String javaBeanPath =javaBeanInstance.getClass().getName();
	     Class<?> clas = Class.forName(javaBeanPath);
	     if(!(clas.isInstance(javaBeanInstance))){
	    	 log.error("传入的java实例与配置的java对象类型不符！");
	      return Xml;
	     }
	     Field[] fields = clas.getDeclaredFields();
	     for (int i = 0; i < fields.length; i++) {
	    	 Method mMethod = null;//方法名
	    	 Field mField = fields[i];//字段名
	    	 String type = fields[i].getType().toString();
	    	 String value ="";
			 String name = "get"+getBeanName(mField.getName());
			 mMethod = clas.getDeclaredMethod(name);
			 if("class java.lang.String".equals(type)){
				 value = (String) mMethod.invoke(javaBeanInstance);
			 }
			 if("class java.lang.Double".equals(type)){
				 DecimalFormat df = new DecimalFormat("0.00");
				 value = df.format(mMethod.invoke(javaBeanInstance)); 
			 }							
			 if ("".equals(value) || value ==null) {
				 if ("N".equals(flag)) {
					;
				}else{
					Xml.append("<"+mField.getName()+">"+value+"</"+mField.getName()+">");
				}
			}else{
				Xml.append("<"+mField.getName()+">"+value+"</"+mField.getName()+">");
			}
		}	     
	    return Xml;
	}

/**
 * 生成xml文件
 * @param xmlStr
 * @param fileName
 * @param flag
 * @return
 */
	public static String createXML(String xmlStr , String fileName, String filePath , int flag) throws Exception {
		Document document  = stringToXML(xmlStr);
		fileName = createXML( document, fileName,filePath,flag ) ;
		return fileName;	
	}
	/**
	 * 创建json文件
	 * @param jsonStr
	 * @param fileName
	 * @param filePath
	 * @param flag
	 * @return
	 * @throws Exception
	 */
	public static String createJSON(String jsonStr , String fileName, String filePath , int flag) throws Exception {
		try {
			File file = new File(filePath+fileName+".json");
			char[] stack = new char[1024];
			int top = -1;
			String string = jsonStr;
			StringBuffer sb = new StringBuffer();
			char[] charArray = string.toCharArray();
			for (int i = 0; i < charArray.length; i++) {
				char c = charArray[i];
				if ('{' == c || '[' == c) {
					stack[++top] = c;
					sb.append("" + charArray[i] + "");
					for (int j = 0; j <= top; j++) {
						sb.append("");
					}
					continue;
				}
				if ((i + 1) <= (charArray.length - 1)) {
					char d = charArray[i + 1];
					if ('}' == d || ']' == d) {
						top--;
						sb.append(charArray[i] + "");
						for (int j = 0; j <= top; j++) {
							sb.append("");
						}
						continue;
					}
				}
				if (',' == c) {
					sb.append(charArray[i] + "");
					for (int j = 0; j <= top; j++) {
						sb.append("");
					}
					continue;
				}
				sb.append(c);
			}
			Writer write = new FileWriter(file);
			write.write(sb.toString());
			write.flush();
			write.close();
		} catch (Exception e) {
		log.error(e.getMessage());
		}
		return fileName;	
	}
/**
 * 生成xml文件
 * @param document
 * @param type
 * @return
 */
	public static String createXML(Document document, String fileName, String filePath, int type) throws Exception {
		if (type ==1) {
			fileName ="UserReq"+fileName;
		}else if (type ==2) {
			fileName ="ReqOther"+fileName;
		}else if (type ==3) {
			fileName ="OtherRes"+fileName;
		}else if (type ==4) {
			fileName ="BackUser"+fileName;
		}else if (type ==5) {
			fileName ="TravelSky"+fileName;
		}
		fileName =fileName.concat(".xml");
		File f = new File(filePath);
		OutputStream out =null;
		if (!f.exists()) {
		f.mkdirs();	
		}
		Format format = Format.getCompactFormat();
		format.setEncoding("UTF-8");
		XMLOutputter XMLOut = new XMLOutputter(format);
		 out = new FileOutputStream(filePath+fileName);
		XMLOut.output(document, out);
		out.close();
		out.close();
		return fileName;
	} 
/**
 * 将Document对象转换成String
 * @param tFileName
 * @return
 */
	public static String XMLFileToString(String tFileName) throws Exception {
		Document document = null;
		SAXBuilder builder = new SAXBuilder();
		document = (Document) builder.build(new File(tFileName));
		XMLOutputter xmlout = new XMLOutputter();
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		xmlout.output(document, bo);
		String xmlStr = bo.toString();
		return xmlStr;
	}
/**
 * 将xml字符串转换为Document对象
 * @param xmlStr
 * @return
 * @throws IOException
 * @throws JDOMException 
 */
	public static Document stringToXML(String xmlStr) throws Exception {
		StringReader sr = new StringReader(xmlStr);
		Document doc = (new SAXBuilder()).build(sr);
		return doc;
	}
/**
 * 把xml的值自动打包成javabean
 * @param javaBeanInstance
 * @param tagsElement
 * @param attName     属性名称
 * @return
 * @throws Exception
 */
	public static Object xmlAttToBean(Object javaBeanInstance, Element tagsElement, String attName) throws Exception {
		Object obj = null;
    	String javaBeanPath =javaBeanInstance.getClass().getName();
    	 Class<?> clas = Class.forName(javaBeanPath);
	     if(!(clas.isInstance(javaBeanInstance))){
	    	 log.error("传入的java实例与配置的java对象类型不符！");
	     }
	     obj=clas.newInstance();
	     for (int i = 0; i < tagsElement.getChildren().size(); i++) {
	    	 Element tagElement = (Element) tagsElement.getChildren().get(i);
	    	 Method mMethod = null;//方法名
	    	 String mField = tagElement.getAttributeValue(attName);//字段名
	    	 String name = "set"+getBeanName(mField);//获取set方法
	    	 mMethod = clas.getDeclaredMethod(name,String.class);
        	// log.debug("=======key:"+mField.getName()+"=======value:"+vElement.getChildText(mField.getName()));
        	mMethod.invoke(obj, tagElement.getValue());
	         //System.out.println("节点名称"+tagElement.getName()+"节点值："+tagElement.getValue()+"节点属性："+tagElement.getAttributeValue("name"));
			}	
		return obj;
	}
/**	
 *  javabean生成  xml
 * @param javaBeanInstance  一个javabean实例
 * @param nodeName
 * @param attName
 * @param flag
 * @return
 */
	public static StringBuilder beanToXmlAtt(Object javaBeanInstance, String nodeName, String attName, String flag) throws Exception {
		StringBuilder Xml = new StringBuilder();
    	String javaBeanPath =javaBeanInstance.getClass().getName();
	     Class<?> clas = Class.forName(javaBeanPath);
	     if(!(clas.isInstance(javaBeanInstance))){
	    	 log.error("传入的java实例与配置的java对象类型不符！");
	      return Xml;
	     }
	     Field[] fields = clas.getDeclaredFields();
	     for (int i = 0; i < fields.length; i++) {
	    	 Method mMethod = null;//方法名
	    	 Field mField = fields[i];//字段名
	    	 String value ="";
			 String name = "get"+getBeanName(mField.getName());
			 mMethod = clas.getDeclaredMethod(name); 
			 value = mMethod.invoke(javaBeanInstance).toString();
			 if ("".equals(value) || value ==null) {
				 if ("N".equals(flag)) {
					;
				}else{
					Xml.append("<"+nodeName+" name=\""+mField.getName()+"\">"+value+"</"+nodeName+">");
				}
			}else{
				Xml.append("<"+nodeName+" name=\""+mField.getName()+"\">"+value+"</"+nodeName+">");
			}
		}	     			
	    return Xml;
	}
	/**
	 * 把xml的值自动打包成javabean
	 * 针对数据类型不只是String的javaBean
	 * @param javaBeanInstance
	 * @param vElement
	 * @return
	 */
	public static Object xmlToObjectBean(Object javaBeanInstance, Element vElement) throws Exception {
		Object obj = null;
    	String javaBeanPath =javaBeanInstance.getClass().getName();
    	 Class<?> clas = Class.forName(javaBeanPath);
	     if(!(clas.isInstance(javaBeanInstance))){
	    	 log.error("传入的java实例与配置的java对象类型不符！");
	     }
	     obj=clas.newInstance();
	     Field[] fields = clas.getDeclaredFields();
	     for (int i = 0; i < fields.length; i++) {//获取所有字段
	    	 Method mMethod = null;//方法名
	    	 Field mField = fields[i];//字段名
	    	 String name = "set"+getBeanName(mField.getName());//获取set方法
	    	 mMethod = clas.getDeclaredMethod(name,fields[i].getType()); 
    		// log.debug("=======key:"+mField.getName()+"=======value:"+vElement.getChildText(mField.getName()));
    		 if("class java.lang.String".equals(fields[i].getType().toString())){
    			 mMethod.invoke(obj, vElement.getChildText(mField.getName()));
    		 }else if("class java.lang.Double".equals(fields[i].getType().toString())){
    			 mMethod.invoke(obj, Double.parseDouble(vElement.getChildText(mField.getName())));
    		 }else if("class java.lang.Integer".equals(fields[i].getType().toString())){
    			 mMethod.invoke(obj, Integer.parseInt((vElement.getChildText(mField.getName()))));
    		 }
	     }
		return obj;	
	}
	//=======================================JSON============================================
		/**
		 * javabean to json
		 * @param JavaBeanInstance
		 * @return
		 * @throws Exception
		 */
		public static String BeanToJson(Object JavaBeanInstance) throws Exception {
			ObjectMapper mapper = new ObjectMapper();
			String Json = "";
			Json = mapper.writeValueAsString(JavaBeanInstance);
			return Json;
		}
		/**
		 * javaListbean to json
		 * @param JavaBeanListInstance
		 * @return
		 * @throws Exception
		 */
		public static String BeanListToJson(List<Object> JavaBeanListInstance) throws Exception {
			ObjectMapper mapper = new ObjectMapper();
			String Json = "";
			int size = JavaBeanListInstance.size();
			for (int i = 0; i < size; i++) {
				if (i == size - 1) {
					Json+= mapper.writeValueAsString(JavaBeanListInstance.get(i));
				}else{
					Json+= mapper.writeValueAsString(JavaBeanListInstance.get(i))+",";
				}
			}
			return Json;
		}
		public static <T> Object JsonToBean(String JsonInstance, Class<T> JavaBeanClass) throws Exception {
			ObjectMapper mapper = new ObjectMapper();
			Object JavaBean = null;
			JavaBean = mapper.readValue(JsonInstance, JavaBeanClass);
			return JavaBean;
		}
		
		public static Object JsonToBean(JSONObject jsob, Object javaBeanInstance) throws Exception {
			Object obj = null;
	   	String javaBeanPath =javaBeanInstance.getClass().getName();
	   	 Class<?> clas = Class.forName(javaBeanPath);
		     if(!(clas.isInstance(javaBeanInstance))){
		    	 log.error("传入的java实例与配置的java对象类型不符！");
		     }
		     obj=clas.newInstance();
		     Field[] fields = clas.getDeclaredFields();
		     for (int i = 0; i < fields.length; i++) {//获取所有字段
		    	 Method mMethod = null;//方法名
		    	 Field mField = fields[i];//字段名
		    	 String name = "set"+getBeanName(mField.getName());//获取set方法
		    	 mMethod = clas.getDeclaredMethod(name,fields[i].getType()); 
		    	try {
		    		 mMethod.invoke(obj, jsob.getString(mField.getName()));
				} catch (Exception e) {
					
				}
		     }
			return obj;	
		}
//=====================================test====================================================
	public static void main(String[] args) {
		try {
			xmlToBean(null,null);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
}